package com.xfg.domain.strategy.service.rule.tree.factory.engine.Impl;

import com.xfg.domain.strategy.model.valobj.RuleLogicCheckTypeV0;
import com.xfg.domain.strategy.model.valobj.RuleTreeNodeLineVO;
import com.xfg.domain.strategy.model.valobj.RuleTreeNodeVO;
import com.xfg.domain.strategy.model.valobj.RuleTreeVO;
import com.xfg.domain.strategy.service.rule.tree.ILogicTreeNode;
import com.xfg.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import com.xfg.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 决策树引擎
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    private final RuleTreeVO ruleTreeV0;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeV0) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeV0 = ruleTreeV0;
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyId, Integer awardId) {
        DefaultTreeFactory.StrategyAwardVO strategyAwardData=null;
        //获取规则树根节点
        String nextNode = ruleTreeV0.getTreeRootRuleNode();
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeV0.getTreeNodeMap();
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);
        while (nextNode!=null){
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey());
            DefaultTreeFactory.TreeActionEntity logicEntity = logicTreeNode.logic(userId, strategyId, awardId);
            RuleLogicCheckTypeV0 ruleLogicCheckTypeVO = logicEntity.getRuleLogicCheckType();
            strategyAwardData = logicEntity.getStrategyAwardVO();
            log.info("决策树引擎 [{}] treeId:{} node:{} code:{}", ruleTreeV0.getTreeName(), ruleTreeV0.getTreeId(), nextNode, ruleLogicCheckTypeVO.getCode());
            nextNode=nextNode(ruleLogicCheckTypeVO.getCode(),ruleTreeNode.getTreeNodeLineVOList());
            ruleTreeNode=treeNodeMap.get(nextNode);
        }
        return strategyAwardData;

    }

    private String  nextNode(String matterValue, List<RuleTreeNodeLineVO> ruleTreeNodeLineVOList) {
        if (ruleTreeNodeLineVOList==null||ruleTreeNodeLineVOList.isEmpty()){
            return null;
        }
        for (RuleTreeNodeLineVO nodeLine : ruleTreeNodeLineVOList) {
            if (decisionLogic(matterValue,nodeLine)){
                return nodeLine.getRuleNodeTo();
            }
        }
        throw new RuntimeException("决策树引擎，nextNode计算失败 未找到可执行节点!");
    }

    public boolean decisionLogic(String matterValue, RuleTreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case EQUAL:
                return matterValue.equals(nodeLine.getRuleLimitValue().getCode());
            // 以下规则暂时不需要实现
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }

}
